<template>
  <div class="op-group comp-op-filter">
    <div class="op-title">筛选</div>
    <template v-for="(modeInfo, modeIndex) in columnSetting">
      <div
        v-if="
          modeInfo.showFunc(
            tableSelectColumns,
            tableSelectColumns.length > 1,
            columnHasNullCell,
            columnFirstCellValue,
            maxMinOptions
          )
        "
        :key="modeInfo.selectionType"
        class="option-item"
      >
        <div class="title-row">
          <span class="label">
            <span
              class="view-icon"
              title="预览"
              @mouseleave="onMouseLeave()"
              @mouseenter="onMouseEnter($event, modeInfo.selectionType)"
            >
              <img src="~@/assets/dataset/preview.png" alt="preview" />
            </span>
            <template v-if="modeInfo.selectionType === 'columnFilterCompare'">
              <compare-filter
                v-if="!modeInfo.isShowSub"
                v-model="bindData.compare"
                :max="maxMinOptions[1]"
                :min="maxMinOptions[0]"
                :default-delimiter="columnFirstCellValue"
                :default-compare-mode="'='"
              >
              </compare-filter>
              <span v-else
                >已选出“{{ bindData.compare.compareMode
                }}{{ bindData.compare.delimiter }}”的单元格</span
              >
            </template>
            <template
              v-else-if="modeInfo.selectionType === 'columnFilterRange'"
            >
              <range-filter
                v-if="!modeInfo.isShowSub"
                v-model="bindData.range"
                :min="maxMinOptions[0]"
                :max="maxMinOptions[1]"
              >
              </range-filter>
              <span v-else
                >已选出“{{ bindData.range.minNumber }}”到“{{
                  bindData.range.maxNumber
                }}”的单元格</span
              >
            </template>
            <template v-else>
              {{
                modeInfo.name(
                  tableSelectColumns,
                  tableSelectColumns.length > 1,
                  columnHasNullCell,
                  columnFirstCellValue
                )
              }}
            </template>
          </span>
          <a-button
            v-if="!modeInfo.isShowSub"
            class="op-btn"
            type="primary"
            size="small"
            @click="showDetail(modeInfo, modeIndex)"
            >确定</a-button
          >
        </div>
        <div v-if="modeInfo.isShowSub" class="detail-panel">
          <h6 class="op-sub-title">操作</h6>
          <div
            v-for="(item, i) in modeInfo.actions"
            :key="i"
            class="sub-item"
            :class="{
              active: value === item.value,
            }"
            @click="onCheckItemClicked(item)"
          >
            <span class="check-item fixed">
              <span
                class="view-icon sub-icon"
                title="预览"
                @mouseleave="onMouseLeave()"
                @mouseenter="onMouseEnter($event, item.value)"
              >
                <img src="~@/assets/dataset/preview.png" alt="preview" />
              </span>
              <status :value="value === item.value"></status>
              <span class="label fixed">{{ item.label }}</span>
            </span>
            <div
              v-if="item.bindKey"
              :key="'input-' + i"
              class="replace-value-box"
              :class="{
                active: value === item.value,
              }"
            >
              <a-input-number
                v-if="isNumberColumn"
                :key="'input-' + i"
                v-model="bindData[item.bindKey]"
                class="replace-value"
                size="small"
                placeholder="Null"
                @change="
                  () => {
                    onInput(item)
                  }
                "
              ></a-input-number>
              <a-input
                v-else
                :key="'input-' + i"
                v-model="bindData[item.bindKey]"
                class="replace-value"
                size="small"
                placeholder="Null"
                @input="
                  () => {
                    onInput(item)
                  }
                "
              ></a-input>
            </div>
          </div>

          <div class="button-row">
            <a-button class="op-btn-sub" size="small" @click="cancel(modeInfo)"
              >取消</a-button
            >
            <a-button
              class="op-btn-sub"
              type="primary"
              size="small"
              @click="doOption"
              >确定</a-button
            >
          </div>
        </div>
      </div>
    </template>
  </div>
</template>
<script lang="ts">
import { isNull, isNumber } from 'lodash'
import DataStore, {
  IColumn,
  OptionPreViewAction,
} from '@/store/modules/dataview'
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
import Status from '../common/status.vue'
import ColumnSettingItem from '../common/column-setting-item-interface'
import compareFilter from '../common/compareFilter.vue'
import rangeFilter from '../common/rangeFilter.vue'
import OptionSettingCommon from '../common/vr-option-set-common'

@Component({
  components: {
    Status,
    compareFilter,
    rangeFilter,
  },
})
export default class ColumnFilter extends Vue {
  /** 操作配置 */
  columnSetting: Array<ColumnSettingItem> = [
    {
      showFunc(
        info: Array<IColumn> | null,
        isMutiple: boolean,
        columnHasNullCell: boolean
      ): boolean {
        return !isMutiple && columnHasNullCell
      },
      selectionType: OptionPreViewAction.columnFilterSelectNullCells,
      name(/* info: Array<IColumn>|null, ...subArgs: Array<any> */): string {
        return '选出该列存在缺失值的单元格'
      },
      actions: [
        {
          label: '为所选单元格重新赋值',
          bindKey: 'replaceValue',
          value: OptionPreViewAction.columnFilterSelectNullCellsReset,
        },
        {
          label: '删除单元格所在的行',
          bindKey: '',
          value: OptionPreViewAction.columnFilterSelectNullCellsDeleteRows,
        },
        {
          label: '仅保留单元格存在的行',
          bindKey: '',
          value: OptionPreViewAction.columnFilterSelectNullCellsKeepRows,
        },
      ],
      isShowSub: false,
    },
    {
      showFunc(
        info: Array<IColumn> | null,
        isMutiple: boolean,
        columnHasNullCell: boolean,
        firstCellValue: any
      ): boolean {
        return !new Set(['', null, undefined]).has(firstCellValue)
      },
      selectionType: OptionPreViewAction.columnFilterContains,
      name(
        info: Array<IColumn> | null,
        isMutiple: boolean,
        columnHasNullCell: boolean,
        columnFirstCellValue: string | number = ''
      ): string {
        return `选出该列值为 ${
          columnFirstCellValue === null || columnFirstCellValue === ''
            ? 'Null'
            : columnFirstCellValue
        } 的单元格`
      },
      actions: [
        {
          label: '为所选单元格重新赋值',
          bindKey: 'replaceValue',
          value: OptionPreViewAction.columnFilterContainsReset,
        },
        {
          label: '删除所选单元格存在的行',
          bindKey: '',
          value: OptionPreViewAction.columnFilterContainsDeleteRows,
        },
        {
          label: '仅保留所选单元格存在的行',
          bindKey: '',
          value: OptionPreViewAction.columnFilterContainsKeepRows,
        },
      ],
      isShowSub: false,
    },
    {
      showFunc(
        info: Array<IColumn> | null,
        mutipleColumn: boolean,
        columnHasNullCell: boolean,
        columnFirstCellValue: any,
        maxMinOptions: Array<number | null>
      ): boolean {
        return (
          info !== null &&
          info[0]?.desc !== undefined &&
          new Set(['decimal', 'int']).has(`${info[0].desc}`) &&
          !mutipleColumn &&
          maxMinOptions[0] !== null &&
          maxMinOptions[1] !== null
        )
      },
      selectionType: OptionPreViewAction.columnFilterCompare,
      name(/* info: Array<IColumn>|null, isMutiple: boolean, columnHasNullCell: boolean, columnFirstCellValue: string|number = '' */): string {
        return ''
      },
      actions: [
        {
          label: '为所选单元格重新赋值',
          bindKey: 'replaceValue',
          value: OptionPreViewAction.columnFilterCompareReset,
        },
        {
          label: '删除所选单元格存在的行',
          bindKey: '',
          value: OptionPreViewAction.columnFilterCompareDeleteRows,
        },
        {
          label: '仅保留所选单元格存在的行',
          bindKey: '',
          value: OptionPreViewAction.columnFilterCompareKeepRows,
        },
      ],
      isShowSub: false,
    },
    {
      showFunc(
        info: Array<IColumn> | null,
        mutipleColumn: boolean,
        columnHasNullCell: boolean,
        columnFirstCellValue: any,
        maxMinOptions: Array<number | null>
      ): boolean {
        return (
          info !== null &&
          info[0]?.desc !== undefined &&
          new Set(['decimal', 'int']).has(`${info[0].desc}`) &&
          !mutipleColumn &&
          maxMinOptions[0] !== null &&
          maxMinOptions[1] !== null
        )
      },
      selectionType: OptionPreViewAction.columnFilterRange,
      name(/* info: Array<IColumn>|null, isMutiple: boolean, columnHasNullCell: boolean, columnFirstCellValue: string|number = '' */): string {
        return ''
      },
      actions: [
        {
          label: '为所选单元格重新赋值',
          bindKey: 'replaceValue',
          value: OptionPreViewAction.columnFilterRangeReset,
        },
        {
          label: '删除所选单元格存在的行',
          bindKey: '',
          value: OptionPreViewAction.columnFilterRangeDeleteRows,
        },
        {
          label: '仅保留所选单元格存在的行',
          bindKey: '',
          value: OptionPreViewAction.columnFilterRangeKeepRows,
        },
      ],
      isShowSub: false,
    },
  ]

  /** 列中是否含有空值 */
  @Prop({
    type: Boolean,
    default() {
      return false
    },
  })
  columnHasNullCell!: boolean

  /** 列中最大值与最小值 */
  @Prop({
    type: Array,
    default() {
      return [null, null]
    },
  })
  maxMinOptions!: Array<number>

  /** 列中首个单元格的值 */
  get columnFirstCellValue() {
    const cellValue = DataStore.tableData[0]
      ? DataStore.tableData[0][this.tableSelectColumns[0].name]
      : ''
    return isNull(cellValue) ? this.maxMinOptions[0] : cellValue
  }

  /** 表的列信息 */
  get tableSelectColumns() {
    return DataStore.tableSelectColumns
  }

  /** 绑定值 */
  value: string = OptionPreViewAction.columnFilterSelectNullCellsReset

  // isShowSub:boolean = false

  replaceValue: string = ''

  bindData: any = {
    replaceValue: '',
    compare: {
      compareMode: '=',
      delimiter: 0,
    },
    range: {
      minNumber: 0,
      maxNumber: 0,
    },
  }

  mounted() {
    DataStore.setColumnFilterSelectNullCellsResetValue(
      this.bindData.replaceValue
    )
    // 默认展示等于第一个单元格的值
    this.$set(this.bindData, 'compare', {
      compareMode: '=',
      delimiter: isNull(this.columnFirstCellValue)
        ? this.maxMinOptions[0]
        : this.columnFirstCellValue,
    })
    DataStore.setTableValueContains([this.columnFirstCellValue])
    DataStore.setVrCompareInfo(this.bindData.compare)
  }

  /**
   * 是否是单列模式且为数值类型的列
   */
  get isNumberColumn() {
    return (
      this.tableSelectColumns.length === 1 &&
      new Set(['decimal', 'int']).has(this.tableSelectColumns[0].desc as any)
    )
  }

  @Watch('columnFirstCellValue')
  getColumnFirstCellValue() {
    this.$set(this.bindData, 'compare', {
      compareMode: '=',
      delimiter: isNull(this.columnFirstCellValue)
        ? this.maxMinOptions[0]
        : this.columnFirstCellValue,
    })
    DataStore.setVrCompareInfo(this.bindData.compare)
    DataStore.setTableValueContains([this.columnFirstCellValue])
  }

  @Watch('maxMinOptions', {
    immediate: true,
    deep: true,
  })
  getMaxMinOptions(newValue: [number | null, number | null]) {
    if (isNumber(newValue[0]) && isNumber(newValue[1])) {
      this.$set(this.bindData, 'compare', {
        compareMode: '=',
        delimiter: isNull(this.columnFirstCellValue)
          ? newValue[0]
          : this.columnFirstCellValue,
      })
      this.$set(this.bindData, 'range', {
        minNumber: newValue[0],
        maxNumber: newValue[1],
      })

      DataStore.setVrRangeInfo([newValue[0], newValue[1]])
      DataStore.setVrCompareInfo({
        compareMode: '=',
        delimiter: isNull(this.columnFirstCellValue)
          ? newValue[0]
          : this.columnFirstCellValue,
      })
    }
  }

  /**
   * 展示操作详情,需要线清对应的属性值并关闭其他已经打开的详情面板
   */
  showDetail(modeInfo: ColumnSettingItem, modeIndex: number) {
    this.columnSetting.forEach((column, columnIndex) => {
      column.isShowSub = modeIndex === columnIndex
    })
    if (modeInfo.actions.length > 0) {
      this.value = modeInfo.actions[0].value
    }
    this.$set(this.bindData, 'replaceValue', '')
    DataStore.setVrCompareInfo(this.bindData.compare)
    DataStore.setTableValueContains([this.columnFirstCellValue])
    DataStore.setVrRangeInfo([
      this.bindData.range.minNumber,
      this.bindData.range.maxNumber,
    ])
    if (
      modeInfo.selectionType === OptionPreViewAction.columnFilterSelectNullCells
    ) {
      OptionSettingCommon.setColumnFilterSelectNullCells(modeInfo)
      this.$message.info('已选出该列中存在缺失值的单元格')
    } else if (
      modeInfo.selectionType === OptionPreViewAction.columnFilterContains
    ) {
      OptionSettingCommon.setColumnFilterContains(modeInfo)
      this.$message.info(
        `已选出该列中值为 ${
          this.columnFirstCellValue === null || this.columnFirstCellValue === ''
            ? 'Null'
            : this.columnFirstCellValue
        } 的单元格`
      )
    } else if (
      modeInfo.selectionType === OptionPreViewAction.columnFilterCompare
    ) {
      OptionSettingCommon.setColumnFilterCompare(modeInfo)
      this.$message.info(
        `已选出该列中值 ${this.bindData.compare.compareMode} ${this.bindData.compare.delimiter} 的单元格`
      )
    } else if (
      modeInfo.selectionType === OptionPreViewAction.columnFilterRange
    ) {
      OptionSettingCommon.setColumnFilterRange(modeInfo)
      this.$message.info(
        `已选出该列中值在 ${this.bindData.range.minNumber} - ${this.bindData.range.maxNumber} 范围的单元格`
      )
    } else {
      DataStore.setTableVrCurrenSetMode(null)
    }
  }

  /** 重置标识 */
  get vrResetTag() {
    return DataStore.vrResetTag
  }

  /** 监听重置标识并执行相关操作 */
  @Watch('vrResetTag')
  getResetTag() {
    this.columnSetting.forEach((item) => {
      item.isShowSub = false
    })
    if (DataStore.vrCurrenSetMode !== null) {
      DataStore.setTableVrCurrenSetMode(null)
    }
  }

  /** 取消操作 */
  cancel(modeInfo: ColumnSettingItem) {
    modeInfo.isShowSub = false
    DataStore.setTableVrCurrenSetMode(null)
  }

  /** 执行操作 */
  doOption() {
    switch (this.value) {
      case OptionPreViewAction.columnFilterSelectNullCellsReset:
        this.$emit('actiondone', {
          action: this.value,
          replaceValue: this.bindData.replaceValue,
          desc:
            '列操作，筛选面板 > 选出该列存在缺失值的单元格 > 为所选单元格重新赋值',
        })
        break
      case OptionPreViewAction.columnFilterSelectNullCellsDeleteRows:
        this.$emit('actiondone', {
          action: this.value,
          desc:
            '列操作，筛选面板 > 选出该列存在缺失值的单元格 > 删除所选单元格存在的行',
        })
        break
      case OptionPreViewAction.columnFilterContainsReset:
        this.$emit('actiondone', {
          action: this.value,
          replaceValue: this.bindData.replaceValue,
          desc: '列操作，筛选面板 > contains > 为所选单元格重新赋值',
        })
        break
      case OptionPreViewAction.columnFilterContainsDeleteRows:
        this.$emit('actiondone', {
          action: this.value,
          desc: '列操作，筛选面板 > contains > 删除所选单元格存在的行',
        })
        break
      case OptionPreViewAction.columnFilterCompareReset:
        this.$emit('actiondone', {
          action: this.value,
          replaceValue: this.bindData.replaceValue,
          desc: '列操作，筛选面板 > 条件对比 > 为所选单元格重新赋值',
        })
        break
      case OptionPreViewAction.columnFilterCompareDeleteRows:
        this.$emit('actiondone', {
          action: this.value,
          desc: '列操作，筛选面板 > 条件对比 > 删除所选单元格存在的行',
        })
        break
      case OptionPreViewAction.columnFilterRangeReset:
        this.$emit('actiondone', {
          action: this.value,
          replaceValue: this.bindData.replaceValue,
          desc: '列操作，筛选面板 > 范围 > 为所选单元格重新赋值',
        })
        break
      case OptionPreViewAction.columnFilterRangeDeleteRows:
        this.$emit('actiondone', {
          action: this.value,
          desc: '列操作，筛选面板 > 范围 > 删除所选单元格存在的行',
        })
        break
      case OptionPreViewAction.columnFilterCompareKeepRows:
        this.$emit('actiondone', {
          action: this.value,
          desc: '列操作，筛选面板 > 范围 > 仅保留所选单元格存在的行',
        })
        break
      case OptionPreViewAction.columnFilterRangeKeepRows:
        this.$emit('actiondone', {
          action: this.value,
          desc: '列操作，筛选面板 > 范围 > 仅保留所选单元格重新赋值',
        })
        break
      case OptionPreViewAction.columnFilterSelectNullCellsKeepRows:
        this.$emit('actiondone', {
          action: this.value,
          desc:
            '列操作，筛选面板 > 选出列种单元格值为Null的单元格 > 仅保留所选单元格存在的行',
        })
        break
      case OptionPreViewAction.columnFilterContainsKeepRows:
        this.$emit('actiondone', {
          action: this.value,
          desc:
            '列操作，筛选面板 > 选出值为xxx的单元格 > 仅保留所选单元格重新赋值',
        })
        break
      default:
        console.error(this.value)
        break
    }
  }

  /** 点击操作 */
  onCheckItemClicked(item: any) {
    this.value = item.value
  }

  /** 输入事件 */
  onInput(item: any) {
    this.$nextTick(() => {
      if (
        new Set([
          OptionPreViewAction.columnFilterSelectNullCellsReset,
          OptionPreViewAction.columnFilterContainsReset,
          OptionPreViewAction.columnFilterCompareReset,
          OptionPreViewAction.columnFilterRangeReset,
        ]).has(item.value)
      ) {
        DataStore.setColumnFilterSelectNullCellsResetValue(
          this.bindData.replaceValue
        )
      }
    })
  }

  /** 预览鼠标移入 */
  onMouseEnter(event: any, action: string) {
    const target = event.target as HTMLElement
    if (target) {
      DataStore.setPreviewAction(action)
      DataStore.setHoverYPos(target.getBoundingClientRect().top - 16)
    }
  }

  /** 预览鼠标移出 */
  onMouseLeave() {
    DataStore.setHoverYPos(-1)
  }
}
</script>
<style lang="less" scoped>
@import url('../op.less');
</style>
